Skip to content

reconcile: the card after a second read (ACE-128) - #310

Open
sandeep-agami wants to merge 6 commits into
ACE-127-reconcile-result-and-fixfrom
ACE-128-reconcile-card-second-read
Open

sandeep-agami wants to merge 6 commits into
ACE-127-reconcile-result-and-fixfrom
ACE-128-reconcile-card-second-read

Conversation

@sandeep-agami

@sandeep-agami sandeep-agami commented Sep 13, 2026

Copy link
Copy Markdown
Collaborator

Spec: ACE-128 (agami-sdlc main, projects/agami-core-extension/specs/reconcile-evidence/ACE-128-card-second-read.md)

Do not merge without manual review. Stacked on #309 (ACE-127); merge bottom-up: #288 → … → #307#309 → this.

Why

Sandeep read the result-and-fix card on a real run and found seven things. Each is fixed here with a test.

# Finding Fix
1 The header is too busy; the question must be clearly visible The question is the card's title; label and source step down to one muted line; the result pill sits at the right
2 One card suggested "add an example", its fix pill said "fix the semantic model", its text said "reword the question" The change text, the to-do, the prefill words and the suggested decision all derive from the one fix. "Add an example" is a decision of its own (example) in the block and the parser, routed by the skill to /agami-save-correction as a prompt example
3 Rows whose only difference is extra columns of yours read "different answer" The comparator's score is 0.0 whenever any column of yours is unpaired, so the share of the score could never be the test. "Partly" is now decided from the comparator's column pairs
4 Columns with different names but the same data counted as a mismatch The compare-results score names column_pairs (which column of yours paired with which of agami's, by values) and unmatched_generated_columns, both additive. The page reads them: a renamed column is the same column, shown as "same values under other names: a → b"; a column of yours with no partner is the mistake; a column only agami returned is noticed
5 Make the checks panel collapsible It folds, open when something did not pass, with "Checks: n passed, m did not" as the summary
6 table.column on one side and column on the other counted as a mismatch In a statement that reads one table, an unqualified column reads as that table's column in the claims reader. With two tables in scope it stays bare. Two ordering pins in test_golden_claims.py requalified deliberately
7 The decision boxes do not prefill Each box starts with the run's words for that row (the gaps to add, the columns to remove, the question to reword) until the person types

Second commit. After Sandeep: "we dont need this explanation with the diff ... use github type formatting if needed" and "the formatting of the tool on a windows machine is not great". The columns row carries no sentence: a column only yours has reads as removed (red, a minus), one only agami's as added (green, a plus), a pair with two names is marked in place with the partner's name on hover (renamed on the diff row). Fonts: the pages named ui-monospace, monospace, which Windows browsers resolve to Courier New, and a Mac-first body stack; every monospace cell now names Cascadia Mono, Cascadia Code and Consolas before the generic, the body names Segoe UI first, the marks and arrows draw from Segoe UI Symbol where it exists, and the value cells sit at 13px.

Third commit. After Sandeep: "the checks panel should be collapsed by default" and "make sure that the colors are consistent. follow a single palette". The checks panel starts closed on every card. One palette, stated once at the top of the shared stylesheet and used by every pill, mark, chip and diff token: green passed/match/keep; red your query; violet the semantic model; amber the question or a check that could not run; blue agami's side (new token --agami: a column only agami returned, add an example, ask again, the suggested decision); gray noted. A legend under the filter rows says the six meanings.

Fourth commit. Sandeep found the mirror cost of the rename fix: identical column names read as a column difference when the row counts differ (13 vs 759), because values cannot pair across vectors of different length. The comparator now reports no pairs and no extras when the counts differ, and the items verb compares columns by data only when a values comparison ran (same counts); otherwise it falls back to names, so identical names are one column set and the rows check alone carries the difference. Tests on both sides.

Review round (/agami-sdlc:review over #304 to #310, three passes). Fixed in the fifth commit: a "same answer, different query" row was never offered for keep; a date window the ledger had confirmed read "could not check" and counted twice; the relative-window fold had no depth budget and could raise out of read_claims on a pathological statement (now eight steps, then None). Nits taken: resume refuses a corrupt checkpoint; a definitional claim that could not be read makes the query fact "not comparable"; a match with an extra column of agami's stays a match and the sentence names the column; a claim that differs is its own amber state (≠) so red keeps one meaning; the intake parser refuses a non-intake rows file and ties the block to the run --out names; intake refuses a file over 20 MB or a CSV cell over the field limit with one line; the page shows only the first line of an error; example is never offered on a row whose ledger holds a mistake; fix words live in one place; the Node page test asserts on CI; em-dashes out of three titles; a tautological assertion and a duplicated check removed. Specs trimmed to decisions in force (ACE-126's build inventories moved here; ACE-128's superseded lines merged; ACE-125 names resume). Declined: deleting the four-beat fallback for older items files (ACE-123's own tests still use that shape; a clean-up when #303 lands); a .gitignore line for a staging folder that should never be created inside a worktree again; --run required on the intake parser (it now derives from --out). Escalated to Sandeep: the rubric pass judges #307 too large (1757 lines, 3.5x the guideline) and asks to lift its library changes (the claims reader's relative windows, the receipt's aggregate flag, the ledger's metric rule) into their own PR between #305 and #307.

Sixth commit. After Sandeep: "the numbers on the Fix pills should get updated, when a filter on Result." The chip counts are facets: each row counts the rows the other filters and the search leave, and a chip whose count fell to zero stays, dimmed, so it can still be toggled.

Decisions

  • Columns are compared by the values they carry, never by name. The comparator already paired them that way; the page now reads the pairing.
  • example is a decision of its own. "Change the semantic model" was the wrong door for a prompt example.
  • Prefill is a start, not a decision. A box the person has typed in is never overwritten.

Tests

  • Comparator: renamed and extra columns as pairs and extras; scalar pair; other levels report nothing. Claims: bare and qualified spellings agree on one table; two tables keep a bare column bare. Items: columns by data with pairs, a fully renamed table as a match, one source for change text and prefill. Parser: the example decision with and without words. Page: question-first head, folding checks, the example option, prefill; the Node smoke test still loads every page. 481 library tests and the reconcile suites green.
  • Full uv run dev.py check on the final commit (7d14fa3): ruff clean, vendored library in sync, 5888 passed, 12 skipped, 1 failed, the failure being tests/test_golden_run.py::test_a_client_that_cannot_be_found_still_fails_as_a_generation, the known local failure on this machine.

History note (review round). Replayed on the rewritten #309 (its staging folder removed); content unchanged.

Rebase note (2026-09-13). Replayed onto main at 99e44a8 with every branch below it; content unchanged, force-pushed with lease.

🤖 Generated with Claude Code

@sandeep-agami
sandeep-agami force-pushed the ACE-127-reconcile-result-and-fix branch from bdf0edc to d6f5d9b Compare September 13, 2026 22:43
@sandeep-agami
sandeep-agami force-pushed the ACE-128-reconcile-card-second-read branch from c41eb57 to eefce79 Compare September 13, 2026 22:43
sandeep-agami added a commit that referenced this pull request Sep 13, 2026
Spec: ACE-128

Three review passes over #304 to #310. Must-fixes: a "same answer, different query" row was never
offered for keep (keep_allowed is the gate's word, whatever the fix); a date window the ledger had
confirmed still read "could not check" and was counted twice (a claim the ledger graded takes the
ledger's word, and a check counts once); the relative-window fold recursed without a depth budget
(eight steps, past which it reads None, so read_claims keeps its promise never to raise). Nits taken:
resume refuses a corrupt checkpoint the way next-chunk does; a definitional claim that could not be
read makes the query fact "not comparable" rather than "same"; a match where agami returned an extra
column stays a match, with the sentence naming the column; a claim that differs between the two
queries is its own state (amber, ≠), so red keeps one meaning; the intake parser refuses a rows file
that is not the intake's output and ties the block to the run named by --out; intake refuses a file
over 20 MB and a CSV cell over the default field limit with one line, never a traceback; the page
shows only the first line of an error; an example is never offered on a row whose ledger holds a
mistake (example_not_offered, read from ledger.json); the fix words live in one place (the items);
the Node page test asserts on CI; three titles lose an em-dash; a tautological assertion, a
duplicated check and two comment periods.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
sandeep-agami and others added 5 commits September 13, 2026 16:33
Spec: ACE-128

Seven findings from Sandeep's read of the result-and-fix card on a real run, fixed together.
(1) The question is the card's title; label and source step down to one muted line; the result pill
sits at the right. (2) The change text, the to-do, the prefill words and the suggested decision all
derive from the one fix; they came from three places and disagreed on one card. "Add an example" is
a decision of its own in the block and the parser, routed to /agami-save-correction as a prompt
example. (3) Extra columns of yours read "different answer" because the score is 0.0 whenever any
column of yours is unpaired; "partly" is now decided from the comparator's column pairs. (4) Columns
are compared by the values they carry, never by name: the comparator score names `column_pairs` and
`unmatched_generated_columns` (additive), a renamed column is the same column and the page says
"same values under other names: a → b". (5) The checks panel folds, open when something did not
pass. (6) In a statement that reads one table, an unqualified column reads as that table's column in
the claims reader, so `opened` and `r.opened` are one claim; with two tables in scope it stays bare
(two ordering pins requalified deliberately). (7) Each decision box starts with the run's words for
that row until the person types.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nder on Windows

Spec: ACE-128

Sandeep: "we dont need this explanation with the diff ... the formatting should make it clear what the
difference is. use github type formatting if needed." The columns row carries no sentence any more: a
column only yours has reads as removed (red, a minus), one only agami's as added (green, a plus), and
a pair with two names is marked in place with the partner's name on hover; the comparator's pairs
travel on the row as `renamed`.

Sandeep: "the formatting of the tool on a windows machine is not great." The pages named
`ui-monospace, monospace`, which Windows browsers resolve to Courier New, and a Mac-first body stack.
Every monospace cell now names Cascadia Mono, Cascadia Code and Consolas before the generic, the body
names Segoe UI first, the marks and arrows draw from Segoe UI Symbol where it exists, and the value
cells sit at 13px.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…one meaning per color

Spec: ACE-128

Sandeep: "the checks panel should be collapsed by default" and "make sure that the colors are
consistent. follow a single palette". The checks panel starts closed on every card; its summary
still says how many passed and how many did not. The palette is stated once at the top of the shared
stylesheet and holds everywhere: green passed, match, keep; red your query; violet the semantic
model; amber the question, a check that could not run, or a partial match; blue agami's side (a
column only agami returned, add an example, ask again, the suggested decision); gray noted, nothing
to fix, could not compare. Blue is new as a token (--agami): before it, agami's side borrowed gray and
an added column borrowed green, so two colors carried two meanings each. A legend under the filter
rows says the six meanings.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nts differ

Spec: ACE-128

Sandeep: "Identical column names read as a column difference. Both sides return exactly ['department',
'pending_items'], yet columns grades defect. Because the row counts differ (13 vs 759), value-based
pairing fails, and the new 'compare by values, never by name' rule then reports identical names as
different columns." Two vectors of different length are never equal, so with differing counts every
column read unpaired: a fact about the counts, not the columns. The comparator now reports no pairs
and no extras when the counts differ, and the items verb compares columns by data only when a values
comparison ran (same counts, and a pairing or an unmatched golden column); otherwise it falls back to
names, so identical names are one column set and the rows check alone carries the difference.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Spec: ACE-128

Three review passes over #304 to #310. Must-fixes: a "same answer, different query" row was never
offered for keep (keep_allowed is the gate's word, whatever the fix); a date window the ledger had
confirmed still read "could not check" and was counted twice (a claim the ledger graded takes the
ledger's word, and a check counts once); the relative-window fold recursed without a depth budget
(eight steps, past which it reads None, so read_claims keeps its promise never to raise). Nits taken:
resume refuses a corrupt checkpoint the way next-chunk does; a definitional claim that could not be
read makes the query fact "not comparable" rather than "same"; a match where agami returned an extra
column stays a match, with the sentence naming the column; a claim that differs between the two
queries is its own state (amber, ≠), so red keeps one meaning; the intake parser refuses a rows file
that is not the intake's output and ties the block to the run named by --out; intake refuses a file
over 20 MB and a CSV cell over the default field limit with one line, never a traceback; the page
shows only the first line of an error; an example is never offered on a row whose ledger holds a
mistake (example_not_offered, read from ledger.json); the fix words live in one place (the items);
the Node page test asserts on CI; three titles lose an em-dash; a tautological assertion, a
duplicated check and two comment periods.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@sandeep-agami
sandeep-agami force-pushed the ACE-127-reconcile-result-and-fix branch from d6f5d9b to 91bb785 Compare September 13, 2026 23:36
@sandeep-agami
sandeep-agami force-pushed the ACE-128-reconcile-card-second-read branch from 7d14fa3 to 8f2f4b4 Compare September 13, 2026 23:36
…s leave

Spec: ACE-128

Sandeep: "the numbers on the Fix pills should get updated, when a filter on Result. currently it
always stays the same." The counts are facets now: the Fix counts follow the Result filter and the
search, the Result counts follow the Fix filter and the search, and a chip whose count fell to zero
stays, dimmed, so it can still be toggled.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant